mkshort becomes a class (#1173)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Wed, 6 Sep 2023 13:34:56 +0000 (07:34 -0600)
committerGitHub <noreply@github.com>
Wed, 6 Sep 2023 13:34:56 +0000 (07:34 -0600)
* make mkshort a class

* add new file mkshort.h

* refactor names

* use bools with mkshort setters

27 files changed:
CMakeLists.txt
defs.h
garmin.cc
garmin_gpi.cc
garmin_gpi.h
gdb.cc
gdb.h
gpx.cc
gpx.h
html.cc
html.h
humminbird.cc
humminbird.h
lowranceusr.cc
lowranceusr.h
main.cc
mkshort.cc
mkshort.h [new file with mode: 0644]
nmea.cc
nmea.h
ozi.cc
text.cc
text.h
tpg.cc
vcf.cc
xcsv.cc
xcsv.h

index 12a6c11c4db43046f2abd8d878ba3a258e68e4bd..476883ccafd0f65e8c99cab5251fe0f3bd354203 100644 (file)
@@ -226,6 +226,7 @@ set(HEADERS
   legacyformat.h
   igc.h
   lowranceusr.h
+  mkshort.h
   nmea.h
   osm.h
   qstarz_bl_1000.h
diff --git a/defs.h b/defs.h
index 59529761a16cebb09cfab5aac8f597327af962e6..2a337c3192eb76a41db142cb9f7cb5fc0efde674 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -838,29 +838,6 @@ using ff_exit = void (*)();
 using ff_writeposn = void (*)(Waypoint*);
 using ff_readposn = Waypoint* (*)(posn_status*);
 
-/*
- * All shortname functions take a shortname handle as the first arg.
- * This is an opaque pointer.  Callers must not fondle the contents of it.
- */
-// This is a crutch until the new C++ shorthandle goes in.
-
-struct mkshort_handle_imp; // forward declare, definition in mkshort.cc
-using short_handle = mkshort_handle_imp*;
-
-QByteArray mkshort(short_handle, const QByteArray&, bool);
-QString mkshort(short_handle, const QString&);
-short_handle mkshort_new_handle();
-QString mkshort_from_wpt(short_handle h, const Waypoint* wpt);
-void mkshort_del_handle(short_handle* h);
-void setshort_length(short_handle, int n);
-void setshort_badchars(short_handle,  const char*);
-void setshort_goodchars(short_handle,  const char*);
-void setshort_mustupper(short_handle,  int n);
-void setshort_mustuniq(short_handle,  int n);
-void setshort_whitespace_ok(short_handle,  int n);
-void setshort_repeating_whitespace_ok(short_handle,  int n);
-void setshort_defname(short_handle, const char* s);
-
 #define ARGTYPE_UNKNOWN    0x00000000U
 #define ARGTYPE_INT        0x00000001U
 #define ARGTYPE_FLOAT      0x00000002U
index 976033291427add693c3f69ff455cd6fd29413e9..159d3c02d9013db8ae6c16a5fb2768ad218c0edf 100644 (file)
--- a/garmin.cc
+++ b/garmin.cc
 #include "jeeps/gpsserial.h"     // for DEFAULT_BAUD
 #include "jeeps/gpsutil.h"       // for GPS_User, GPS_Enable_Diagnose, GPS_E...
 #include "src/core/datetime.h"   // for DateTime
+#include "mkshort.h"             // for MakeShort
 
 
 #define MYNAME "GARMIN"
 static const char* portname;
-static short_handle mkshort_handle;
+static MakeShort* mkshort_handle;
 static GPS_PWay* tx_waylist;
 static GPS_PWay* tx_routelist;
 static GPS_PWay* cur_tx_routelist_entry;
@@ -75,7 +76,7 @@ static char* baudopt = nullptr;
 static char* opt_codec = nullptr;
 static int baud = 0;
 static int categorybits;
-static int receiver_must_upper = 1;
+static bool receiver_must_upper = true;
 static QTextCodec* codec{nullptr};
 
 #define MILITANT_VALID_WAYPT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
@@ -155,11 +156,11 @@ write_char_string(char* dest, const char* source, size_t destsize)
 static void
 rw_init(const QString& fname)
 {
-  receiver_must_upper = 1;
+  receiver_must_upper = true;
   const char* receiver_charset = "US-ASCII";
 
   if (!mkshort_handle) {
-    mkshort_handle = mkshort_new_handle();
+    mkshort_handle = new MakeShort;
   }
 
   if (global_opts.debug_level > 0)  {
@@ -218,7 +219,7 @@ rw_init(const QString& fname)
   }
 
   /*
-   * Grope the unit we're talking to to set setshort_length to
+   * Grope the unit we're talking to to set set_length to
    *   20 for  the V,
    *   10 for Street Pilot, (old) Rhino, 76
    *   6 for the III, 12, emap, and etrex
@@ -260,7 +261,7 @@ rw_init(const QString& fname)
     case 574:  /* Geko 201 */
       receiver_short_length = 6;
       valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-";
-      setshort_badchars(mkshort_handle, "\"$.,'!");
+      mkshort_handle->set_badchars("\"$.,'!");
       break;
 
     case 155:  /* Garmin V */
@@ -270,7 +271,7 @@ rw_init(const QString& fname)
       break;
     case 382:  /* C320 */
       receiver_short_length = 30;
-      receiver_must_upper = 0;
+      receiver_must_upper = false;
       break;
     case 292: /* (60|76)C[S]x series */
     case 421: /* Vista|Legend Cx */
@@ -280,7 +281,7 @@ rw_init(const QString& fname)
     case 957: /* Legend HC */
       receiver_short_length = 14;
       snwhiteopt = xstrdup("1");
-      receiver_must_upper = 0;
+      receiver_must_upper = false;
       /* This might be 8859-1 */
       receiver_charset = "windows-1252";
       break;
@@ -288,20 +289,20 @@ rw_init(const QString& fname)
     case 1095: /* GPS 72H */
       receiver_short_length = 10;
       valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-";
-      setshort_badchars(mkshort_handle, "\"$.,'!");
+      mkshort_handle->set_badchars("\"$.,'!");
       break;
     case 231: /* Quest */
     case 463: /* Quest 2 */
-      receiver_must_upper = 0;
+      receiver_must_upper = false;
       receiver_short_length = 30;
       receiver_charset = "windows-1252";
       break;
     case 577: // Rino 530HCx Version 2.50
-      receiver_must_upper = 0;
+      receiver_must_upper = false;
       receiver_short_length = 14;
       break;
     case 429: // Streetpilot i3
-      receiver_must_upper = 0;
+      receiver_must_upper = false;
       receiver_charset = "windows-1252";
       receiver_short_length = 30;
       break;
@@ -332,13 +333,13 @@ rw_init(const QString& fname)
    * If the user provided a short_length, override the calculated value.
    */
   if (snlen) {
-    setshort_length(mkshort_handle, xstrtoi(snlen, nullptr, 10));
+    mkshort_handle->set_length(xstrtoi(snlen, nullptr, 10));
   } else {
-    setshort_length(mkshort_handle, receiver_short_length);
+    mkshort_handle->set_length(receiver_short_length);
   }
 
   if (snwhiteopt) {
-    setshort_whitespace_ok(mkshort_handle, xstrtoi(snwhiteopt, nullptr, 10));
+    mkshort_handle->set_whitespace_ok(xstrtoi(snwhiteopt, nullptr, 10));
   }
 
   /*
@@ -346,12 +347,12 @@ rw_init(const QString& fname)
    * for the new models, we just release this safety check manually.
    */
   if (receiver_must_upper) {
-    setshort_goodchars(mkshort_handle, valid_waypt_chars);
+    mkshort_handle->set_goodchars(valid_waypt_chars);
   } else {
-    setshort_badchars(mkshort_handle, "");
+    mkshort_handle->set_badchars("");
   }
 
-  setshort_mustupper(mkshort_handle, receiver_must_upper);
+  mkshort_handle->set_mustupper(receiver_must_upper);
 
   /*
    * This used to mean something when we used cet, but these days this
@@ -398,9 +399,8 @@ rw_deinit()
     }
   }
 
-  if (mkshort_handle) {
-    mkshort_del_handle(&mkshort_handle);
-  }
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
 
   xfree(portname);
   portname = nullptr;
@@ -888,7 +888,7 @@ waypoint_prepare()
      * mkshort will do collision detection and namespace
      * cleaning
      */
-    QByteArray ident = mkshort(mkshort_handle,
+    QByteArray ident = mkshort_handle->mkshort(
                                global_opts.synthesize_shortnames ?
                                str_from_unicode(src) :
                                str_from_unicode(wpt->shortname),
index 473871bb234419e6c9ce2e24b2f5cee8e35fa70d..793c3c117dde79b2b4c557d610f3f7e66b58ddde 100644 (file)
@@ -1044,7 +1044,7 @@ GarminGPIFormat::enum_waypt_cb(const Waypoint* ref) const
   auto* wpt = new Waypoint(*ref);
 
   if (*opt_unique == '1') {
-    wpt->shortname = mkshort(short_h, wpt->shortname);
+    wpt->shortname = short_h->mkshort(wpt->shortname);
   }
 
   wdata_add_wpt(wdata, wpt);
@@ -1252,15 +1252,15 @@ GarminGPIFormat::wr_init(const QString& fname)
 
   fout = gbfopen_le(fname, "wb", MYNAME);
 
-  short_h = mkshort_new_handle();
+  short_h = new MakeShort;
 
-  setshort_length(short_h, 1024);
-  setshort_badchars(short_h, "\r\n");
-  setshort_mustupper(short_h, 0);
-  setshort_mustuniq(short_h, 1);
-  setshort_whitespace_ok(short_h, 1);
-  setshort_repeating_whitespace_ok(short_h, 0);
-  setshort_defname(short_h, "POI");
+  short_h->set_length(1024);
+  short_h->set_badchars("\r\n");
+  short_h->set_mustupper(false);
+  short_h->set_mustuniq(true);
+  short_h->set_whitespace_ok(true);
+  short_h->set_repeating_whitespace_ok(false);
+  short_h->set_defname("POI");
 
   codepage = 0;
 
@@ -1325,7 +1325,8 @@ void
 GarminGPIFormat::wr_deinit()
 {
   wdata_free(wdata);
-  mkshort_del_handle(&short_h);
+  delete short_h;
+  short_h = nullptr;
   gbfclose(fout);
 
   if ((opt_sleep) && !gpsbabel_testmode()) {  /* don't sleep during 'testo' */
index d13920184b57679ed8fe163191d520832bdc2aec..5594f6ffc9af813b47916673bc43380a8e2e341e 100644 (file)
 #include <cstdint>      // for int32_t, int16_t, uint16_t
 #include <ctime>        // for time_t
 
-#include "defs.h"       // for arglist_t, ARG_NOMINMAX, ff_cap, Waypoint, ARGTYPE_BOOL, ARGTYPE_STRING, ff_cap_none, ARGTYPE_FILE, ARGTYPE_INT, bounds, ff_cap_read, ff_cap_write, ff_type, ff_type_file, short_handle
+#include "defs.h"       // for arglist_t, ARG_NOMINMAX, ff_cap, Waypoint, ARGTYPE_BOOL, ARGTYPE_STRING, ff_cap_none, ARGTYPE_FILE, ARGTYPE_INT, bounds, ff_cap_read, ff_cap_write, ff_type, ff_type_file
 #include "format.h"     // for Format
 #include "garmin_fs.h"  // for garmin_fs_t
 #include "gbfile.h"     // for gbfile
+#include "mkshort.h"    // for MakeShort
 
 
 class GarminGPIFormat : public Format
@@ -377,7 +378,7 @@ private:
   uint16_t codepage{}; /* code-page, e.g. 1252, 65001 */
   reader_data_t* rdata{};
   writer_data_t* wdata{};
-  short_handle short_h{};
+  MakeShort* short_h{};
   char units{};
   time_t gpi_timestamp = 0;
   QTextCodec* codec{nullptr};
diff --git a/gdb.cc b/gdb.cc
index 347af342f1a6d6e01981a24258ebc80f05663c7c..5efbb55f33a8ad0d9d1d4881c6ca197899642826 100644 (file)
--- a/gdb.cc
+++ b/gdb.cc
 #include <cstring>                  // for memset, strstr, strcmp
 #include <iterator>                 // for next
 
-#include "defs.h"                   // for Waypoint, warning, route_head, fatal, UrlLink, bounds, mkshort, UrlList, unknown_alt, xfree, waypt_add_to_bounds, waypt_init_bounds, xstrtoi, mkshort_del_handle, route_add_wpt, route_disp_all, waypt_bounds_valid, xmalloc, gb_color, WaypointList, find_wa...
+#include "defs.h"                   // for Waypoint, warning, route_head, fatal, UrlLink, bounds, UrlList, unknown_alt, xfree, waypt_add_to_bounds, waypt_init_bounds, xstrtoi, route_add_wpt, route_disp_all, waypt_bounds_valid, xmalloc, gb_color, WaypointList, find_wa...
 #include "formspec.h"               // for FormatSpecificDataList
 #include "garmin_fs.h"              // for garmin_fs_t, garmin_ilink_t, garmin_fs_alloc
 #include "garmin_tables.h"          // for gt_waypt_class_map_point, gt_color_index_by_rgb, gt_color_value, gt_waypt_classes_e, gt_find_desc_from_icon_number, gt_find_icon_number_from_desc, gt_gdb_display_mode_symbol, gt_get_icao_country, gt_waypt_class_user_waypoint, GDB, gt_display_mode_symbol
 #include "gbfile.h"                 // for gbfgetint32, gbfputint32, gbfgetc, gbfread, gbfwrite, gbfgetdbl, gbfputc, gbfgetcstr, gbfclose, gbfgetnativecstr, gbfopen_le, gbfputint16, gbfile, gbfcopyfrom, gbfputcstr, gbfrewind, gbfseek, gbftell, gbfgetcstr_old, gbfgetint16, gbfgetuint32, gbfputdbl
 #include "grtcirc.h"                // for RAD, gcdist, radtometers
 #include "jeeps/gpsmath.h"          // for GPS_Math_Deg_To_Semi, GPS_Math_Semi_To_Deg
+#include "mkshort.h"                // for MakeShort
 #include "src/core/datetime.h"      // for DateTime
 
 
@@ -1113,19 +1114,17 @@ GdbFormat::read()
 void
 GdbFormat::reset_short_handle(const char* defname)
 {
-  if (short_h != nullptr) {
-    mkshort_del_handle(&short_h);
-  }
+  delete short_h;
 
-  short_h = mkshort_new_handle();
+  short_h = new MakeShort;
 
-  setshort_length(short_h, kGDBNameBufferLen);
-  setshort_badchars(short_h, "\r\n\t");
-  setshort_mustupper(short_h, 0);
-  setshort_mustuniq(short_h, 1);
-  setshort_whitespace_ok(short_h, 1);
-  setshort_repeating_whitespace_ok(short_h, 1);
-  setshort_defname(short_h, defname);
+  short_h->set_length(kGDBNameBufferLen);
+  short_h->set_badchars("\r\n\t");
+  short_h->set_mustupper(false);
+  short_h->set_mustuniq(true);
+  short_h->set_whitespace_ok(true);
+  short_h->set_repeating_whitespace_ok(true);
+  short_h->set_defname(defname);
 }
 
 /* ----------------------------------------------------------------------------*/
@@ -1613,7 +1612,7 @@ GdbFormat::write_waypoint_cb(const Waypoint* refpt)
       }
     }
 
-    name = mkshort(short_h, name);
+    name = short_h->mkshort(name);
     wpt->extra_data = new QString(name);
     write_waypoint(wpt, name, gmsd, icon, display);
 
@@ -1630,9 +1629,9 @@ GdbFormat::write_route_cb(const route_head* rte)
 
   QString name;
   if (rte->rte_name.isNull()) {
-    name = mkshort(short_h, QString::asprintf("Route%04d", rte->rte_num));
+    name = short_h->mkshort(QString::asprintf("Route%04d", rte->rte_num));
   } else {
-    name = mkshort(short_h, rte->rte_name);
+    name = short_h->mkshort(rte->rte_name);
   }
 
   rte_ct++;    /* increase informational number of written routes */
@@ -1652,9 +1651,9 @@ GdbFormat::write_track_cb(const route_head* trk)
 
   QString name;
   if (trk->rte_name.isNull()) {
-    name = mkshort(short_h, QString::asprintf("Track%04d", trk->rte_num));
+    name = short_h->mkshort(QString::asprintf("Track%04d", trk->rte_num));
   } else {
-    name = mkshort(short_h, trk->rte_name);
+    name = short_h->mkshort(trk->rte_name);
   }
 
   trk_ct++;    /* increase informational number of written tracks */
@@ -1704,7 +1703,8 @@ GdbFormat::wr_deinit()
 {
   disp_summary(fout);
   gdb_flush_waypt_queue(waypt_nameposn_out_hash);
-  mkshort_del_handle(&short_h);
+  delete short_h;
+  short_h = nullptr;
   gbfclose(fout);
   gbfclose(ftmp);
 }
diff --git a/gdb.h b/gdb.h
index b418a51a18975736f5de08187213ec2a6b8b8f04..1e30b7b6ca43d422b0ea2ba814d85db5d7b0b500 100644 (file)
--- a/gdb.h
+++ b/gdb.h
 #include <QVector>          // for QVector
 #include <QtGlobal>         // for QT_VERSION, QT_VERSION_CHECK
 
-#include "defs.h"           // for arglist_t, Waypoint, route_head, ARGTYPE_BOOL, ARGTYPE_INT, ARG_NOMINMAX, bounds, FF_CAP_RW_ALL, ff_cap, ff_type, ff_type_file, short_handle
+#include "defs.h"           // for arglist_t, Waypoint, route_head, ARGTYPE_BOOL, ARGTYPE_INT, ARG_NOMINMAX, bounds, FF_CAP_RW_ALL, ff_cap, ff_type, ff_type_file
 #include "format.h"         // for Format
 #include "garmin_fs.h"      // for garmin_fs_t
 #include "garmin_tables.h"  // for gt_waypt_classes_e
 #include "gbfile.h"         // for gbfile
+#include "mkshort.h"        // for MakeShort
 
 
 class GdbFormat : public Format
@@ -172,7 +173,7 @@ private:
   WptNamePosnHash waypt_nameposn_in_hidden_hash;
   WptNameHash waypt_name_in_hidden_hash;
   WptNamePosnHash waypt_nameposn_out_hash;
-  short_handle short_h{};
+  MakeShort* short_h{};
 
   char* gdb_opt_category{};
   char* gdb_opt_ver{};
diff --git a/gpx.cc b/gpx.cc
index 4e591b33e2de11c4af5853f7624ad22b0bceda83..6d0a4c0428afef87a95e6d864cf668b1cfc227a4 100644 (file)
--- a/gpx.cc
+++ b/gpx.cc
@@ -49,6 +49,7 @@
 #include "garmin_fs.h"                      // for garmin_fs_xml_convert, garmin_fs_xml_fprint, GMSD_FIND
 #include "garmin_tables.h"                  // for gt_color_index_by_rgb, gt_color_name, gt_color_value_by_name
 #include "geocache.h"                       // for Geocache, Geocache::UtfSt...
+#include "mkshort.h"                        // for MakeShort
 #include "src/core/datetime.h"              // for DateTime
 #include "src/core/file.h"                  // for File
 #include "src/core/logging.h"               // for Warning, Fatal
@@ -90,17 +91,15 @@ inline QString GpxFormat::toString(float f)
 void
 GpxFormat::gpx_reset_short_handle()
 {
-  if (mkshort_handle != nullptr) {
-    mkshort_del_handle(&mkshort_handle);
-  }
+  delete mkshort_handle;
 
-  mkshort_handle = mkshort_new_handle();
+  mkshort_handle = new MakeShort;
 
   if (suppresswhite) {
-    setshort_whitespace_ok(mkshort_handle, 0);
+    mkshort_handle->set_whitespace_ok(false);
   }
 
-  setshort_length(mkshort_handle, xstrtoi(snlen, nullptr, 10));
+  mkshort_handle->set_length(xstrtoi(snlen, nullptr, 10));
 }
 
 void
@@ -971,7 +970,8 @@ GpxFormat::wr_deinit()
   delete oqfile;
   oqfile = nullptr;
 
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
 }
 
 QString
@@ -1323,7 +1323,7 @@ GpxFormat::gpx_waypt_pr(const Waypoint* waypointp) const
   writer->writeAttribute(QStringLiteral("lon"), toString(waypointp->longitude));
 
   QString oname = global_opts.synthesize_shortnames ?
-                  mkshort_from_wpt(mkshort_handle, waypointp) :
+                  mkshort_handle->mkshort_from_wpt(waypointp) :
                   waypointp->shortname;
   gpx_write_common_position(waypointp, gpxpt_waypoint);
   gpx_write_common_description(waypointp, oname);
@@ -1402,7 +1402,7 @@ GpxFormat::gpx_track_disp(const Waypoint* waypointp) const
   gpx_write_common_position(waypointp, gpxpt_track);
 
   QString oname = global_opts.synthesize_shortnames ?
-                  mkshort_from_wpt(mkshort_handle, waypointp) :
+                  mkshort_handle->mkshort_from_wpt(waypointp) :
                   waypointp->shortname;
   gpx_write_common_description(waypointp,
                                waypointp->wpt_flags.shortname_is_synthetic ?
@@ -1491,7 +1491,7 @@ GpxFormat::gpx_route_disp(const Waypoint* waypointp) const
   writer->writeAttribute(QStringLiteral("lon"), toString(waypointp->longitude));
 
   QString oname = global_opts.synthesize_shortnames ?
-                  mkshort_from_wpt(mkshort_handle, waypointp) :
+                  mkshort_handle->mkshort_from_wpt(waypointp) :
                   waypointp->shortname;
   gpx_write_common_position(waypointp, gpxpt_route);
   gpx_write_common_description(waypointp, oname);
diff --git a/gpx.h b/gpx.h
index f02da3b2133d05e9194709347d31b4b9a53e5493..1fd5b9692b2e82bd41fc97134ad4377d7c226731 100644 (file)
--- a/gpx.h
+++ b/gpx.h
@@ -34,6 +34,7 @@
 #include "defs.h"
 #include "format.h"                    // for Format
 #include "formspec.h"                  // for FormatSpecificData
+#include "mkshort.h"                   // for MakeShort
 #include "src/core/file.h"             // for File
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
 #include "src/core/xmltag.h"           // for xml_tag
@@ -243,7 +244,7 @@ private:
   gpsbabel::File* iqfile{};
   gpsbabel::File* oqfile{};
   gpsbabel::XmlStreamWriter* writer{};
-  short_handle mkshort_handle{};
+  MakeShort* mkshort_handle{};
   QString link_url;
   QString link_text;
   QString link_type;
diff --git a/html.cc b/html.cc
index 54ca3842858f801770cedd9bec5cb24fa9664a6c..3273a1d96e70ce1724902c0c0f3fe259fc5944ba 100644 (file)
--- a/html.cc
+++ b/html.cc
@@ -33,6 +33,7 @@
 #include "formspec.h"              // for FormatSpecificDataList, kFsGpx
 #include "geocache.h"              // for Geocache, Geocache::UtfString
 #include "jeeps/gpsmath.h"         // for GPS_Math_WGS84_To_UTM_EN
+#include "mkshort.h"               // for MakeShort
 #include "src/core/datetime.h"     // for DateTime
 #include "src/core/textstream.h"   // for TextStream
 #include "src/core/xmltag.h"       // for xml_findfirst, xml_tag, xml_attribute, fs_xml, xml_findnext
@@ -45,7 +46,7 @@ HtmlFormat::wr_init(const QString& fname)
 {
   file_out = new gpsbabel::TextStream;
   file_out->open(fname, QIODevice::WriteOnly, MYNAME);
-  mkshort_handle = mkshort_new_handle();
+  mkshort_handle = new MakeShort;
 }
 
 void
@@ -54,7 +55,8 @@ HtmlFormat::wr_deinit()
   file_out->close();
   delete file_out;
   file_out = nullptr;
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
 }
 
 QString HtmlFormat::create_id(int sequence_number)
@@ -78,7 +80,7 @@ HtmlFormat::html_disp(const Waypoint* wpt) const
 
   *file_out << "  <div id=\"" << create_id(waypoint_number) << "\"><hr>\n";
   *file_out << "    <table style=\"width:100%\">\n";
-  QString sn = global_opts.synthesize_shortnames ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname;
+  QString sn = global_opts.synthesize_shortnames ? mkshort_handle->mkshort_from_wpt(wpt) : wpt->shortname;
   *file_out << "      <tr>\n";
   *file_out << "        <td>\n";
   *file_out << "          <p class=\"gpsbabelwaypoint\">" << sn << " - ";
@@ -216,7 +218,7 @@ HtmlFormat::html_index(const Waypoint* wpt) const
 void
 HtmlFormat::write()
 {
-  setshort_length(mkshort_handle, 6);
+  mkshort_handle->set_length(6);
 
   *file_out << "<!DOCTYPE html>\n";
   *file_out << "<html>\n";
diff --git a/html.h b/html.h
index 87ba8c0a936ec33fd985f9a042094938bd95f176..0e930ba2ff7c44649b647ad05a79a9686636debc 100644 (file)
--- a/html.h
+++ b/html.h
@@ -26,6 +26,7 @@
 
 #include "defs.h"
 #include "format.h"               // for Format
+#include "mkshort.h"              // for MakeShort
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -62,7 +63,7 @@ private:
   /* Data Members */
 
   gpsbabel::TextStream* file_out{nullptr};
-  short_handle mkshort_handle{};
+  MakeShort* mkshort_handle{};
 
   int waypoint_number{};
 
index 95b4453eda55093a19caf2634b9290f044826ced..ea3f2f3a82eae52b9b4a5259b0db2a5268ed281e 100644 (file)
@@ -29,7 +29,8 @@
 #include <cstdio>               // for snprintf, SEEK_SET
 #include <cstring>              // for strncpy, memcpy, memset
 
-#include "defs.h"               // for Waypoint, be_read32, be_read16, be_write32, fatal, xfree, be_write16, route_head, xcalloc, track_add_wpt, xstrndup, mkshort, mkshort_del_handle, mkshort_new_handle, setshort_badchars, setshort_defname, setshort_length, setshort_mustuniq, setshort_...
+#include "defs.h"               // for Waypoint, be_read32, be_read16, be_write32, fatal, xfree, be_write16, route_head, xcalloc, track_add_wpt, xstrndup
+#include "mkshort.h"            // for MakeShort
 #include "src/core/datetime.h"  // for DateTime
 
 
@@ -582,33 +583,33 @@ HumminbirdBase::humminbird_wr_init(const QString& fname)
 {
   fout_ = gbfopen_be(fname, "wb", MYNAME);
 
-  wptname_sh = mkshort_new_handle();
-
-  setshort_length(wptname_sh, WPT_NAME_LEN - 1);
-  setshort_badchars(wptname_sh, BAD_CHARS);
-  setshort_mustupper(wptname_sh, 0);
-  setshort_mustuniq(wptname_sh, 0);
-  setshort_whitespace_ok(wptname_sh, 1);
-  setshort_repeating_whitespace_ok(wptname_sh, 1);
-  setshort_defname(wptname_sh, "WPT");
-
-  rtename_sh = mkshort_new_handle();
-  setshort_length(rtename_sh, RTE_NAME_LEN - 1);
-  setshort_badchars(rtename_sh, BAD_CHARS);
-  setshort_mustupper(rtename_sh, 0);
-  setshort_mustuniq(rtename_sh, 0);
-  setshort_whitespace_ok(rtename_sh, 1);
-  setshort_repeating_whitespace_ok(rtename_sh, 1);
-  setshort_defname(rtename_sh, "Route");
-
-  trkname_sh = mkshort_new_handle();
-  setshort_length(trkname_sh, RTE_NAME_LEN - 1);
-  setshort_badchars(trkname_sh, BAD_CHARS);
-  setshort_mustupper(trkname_sh, 0);
-  setshort_mustuniq(trkname_sh, 0);
-  setshort_whitespace_ok(trkname_sh, 1);
-  setshort_repeating_whitespace_ok(trkname_sh, 1);
-  setshort_defname(trkname_sh, "Track");
+  wptname_sh = new MakeShort;
+
+  wptname_sh->set_length(WPT_NAME_LEN - 1);
+  wptname_sh->set_badchars(BAD_CHARS);
+  wptname_sh->set_mustupper(false);
+  wptname_sh->set_mustuniq(false);
+  wptname_sh->set_whitespace_ok(true);
+  wptname_sh->set_repeating_whitespace_ok(true);
+  wptname_sh->set_defname("WPT");
+
+  rtename_sh = new MakeShort;
+  rtename_sh->set_length(RTE_NAME_LEN - 1);
+  rtename_sh->set_badchars(BAD_CHARS);
+  rtename_sh->set_mustupper(false);
+  rtename_sh->set_mustuniq(false);
+  rtename_sh->set_whitespace_ok(true);
+  rtename_sh->set_repeating_whitespace_ok(true);
+  rtename_sh->set_defname("Route");
+
+  trkname_sh = new MakeShort;
+  trkname_sh->set_length(RTE_NAME_LEN - 1);
+  trkname_sh->set_badchars(BAD_CHARS);
+  trkname_sh->set_mustupper(false);
+  trkname_sh->set_mustuniq(false);
+  trkname_sh->set_whitespace_ok(true);
+  trkname_sh->set_repeating_whitespace_ok(true);
+  trkname_sh->set_defname("Track");
 
   waypoint_num = 0;
   rte_num_ = 0;
@@ -617,9 +618,12 @@ HumminbirdBase::humminbird_wr_init(const QString& fname)
 void
 HumminbirdBase::humminbird_wr_deinit()
 {
-  mkshort_del_handle(&wptname_sh);
-  mkshort_del_handle(&rtename_sh);
-  mkshort_del_handle(&trkname_sh);
+  delete wptname_sh;
+  wptname_sh = nullptr;
+  delete rtename_sh;
+  rtename_sh = nullptr;
+  delete trkname_sh;
+  trkname_sh = nullptr;
   gbfclose(fout_);
 }
 
@@ -666,8 +670,8 @@ HumminbirdFormat::humminbird_write_waypoint(const Waypoint* wpt)
   be_write32(&hum.north, qRound(north));
 
   QString name = (global_opts.synthesize_shortnames)
-                 ? mkshort_from_wpt(wptname_sh, wpt)
-                 : mkshort(wptname_sh, wpt->shortname);
+                 ? wptname_sh->mkshort_from_wpt(wpt)
+                 : wptname_sh->mkshort(wpt->shortname);
   memset(&hum.name, 0, sizeof(hum.name));
   memcpy(&hum.name, CSTR(name), name.length());
 
@@ -686,7 +690,7 @@ HumminbirdHTFormat::humminbird_track_head(const route_head* trk)
     trk_head = (humminbird_trk_header_t*) xcalloc(1, sizeof(humminbird_trk_header_t));
     trk_points = (humminbird_trk_point_t*) xcalloc(max_points, sizeof(humminbird_trk_point_t));
 
-    QString name = mkshort(trkname_sh, trk->rte_name);
+    QString name = trkname_sh->mkshort(trk->rte_name);
     strncpy(trk_head->name, CSTR(name), sizeof(trk_head->name)-1);
     be_write16(&trk_head->trk_num, trk->rte_num);
   }
@@ -835,7 +839,7 @@ HumminbirdFormat::humminbird_rte_tail(const route_head* rte)
     be_write16(&humrte->num, humrte->num);
     be_write32(&humrte->time, humrte->time);
 
-    QString name = mkshort(rtename_sh, rte->rte_name);
+    QString name = rtename_sh->mkshort(rte->rte_name);
     strncpy(humrte->name, CSTR(name), sizeof(humrte->name)-1);
 
     gbfputuint32(RTE_MAGIC, fout_);
index 9e7a43bdcd9e4663397e0d3f1b81991a4f43938f..17f0c44c81a077a36b8d3236d50df8d0c6e2bd94 100644 (file)
@@ -30,6 +30,7 @@
 #include "defs.h"    // for ff_cap, arglist_t, ff_cap_read, Waypoint, route_head, ff_cap_write, short_handle, ff_type, ff_type_file
 #include "format.h"  // for Format
 #include "gbfile.h"  // for gbfile
+#include "mkshort.h" // for MakeShort
 
 
 class HumminbirdBase
@@ -102,7 +103,9 @@ protected:
   gbfile* fin_{};
   gbfile* fout_{};
   int waypoint_num{};
-  short_handle wptname_sh{}, rtename_sh{}, trkname_sh{};
+  MakeShort* wptname_sh{};
+  MakeShort* rtename_sh{};
+  MakeShort* trkname_sh{};
   humminbird_rte_t* humrte{};
   int rte_num_{};
   QMap<QString, Waypoint*> map;
index 89a61585b99b22896f49135b5816ef1f39648d22..cbfd1f05ccd310f3681f9fcd1b343ab46f6c2b0e 100644 (file)
@@ -342,7 +342,7 @@ void
 LowranceusrFormat::wr_init(const QString& fname)
 {
   file_out = gbfopen_le(fname, "wb", MYNAME);
-  mkshort_handle = mkshort_new_handle();
+  mkshort_handle = new MakeShort;
   waypt_out_count = 0;
   writing_version = xstrtoi(opt_wversion, nullptr, 10);
   if ((writing_version < 2) || (writing_version > 4)) {
@@ -356,7 +356,8 @@ void
 LowranceusrFormat::wr_deinit()
 {
   gbfclose(file_out);
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
   utf16le_codec = nullptr;
   delete waypt_table;
   waypt_table = nullptr;
@@ -1284,7 +1285,7 @@ LowranceusrFormat::lowranceusr_waypt_disp(const Waypoint* wpt) const
   QString name;
   if ((wpt->shortname.isEmpty()) || global_opts.synthesize_shortnames) {
     if (!wpt->description.isEmpty() && global_opts.synthesize_shortnames) {
-      name = mkshort_from_wpt(mkshort_handle, wpt);
+      name = mkshort_handle->mkshort_from_wpt(wpt);
     } else if (!wpt->shortname.isEmpty()) {
       name = wpt->shortname;
     } else if (!wpt->description.isEmpty()) {
@@ -1835,7 +1836,7 @@ LowranceusrFormat::write()
 {
   QString buf;
 
-  setshort_length(mkshort_handle, 15);
+  mkshort_handle->set_length(15);
 
   gbfputint32(writing_version, file_out);
 
index 6013fdb279ff2c14a9fdcd2a6032b1dd373de67c..51b4dbeed78e0f95ee6735347b3ff4740d42b7a8 100644 (file)
 #include "format.h"
 #include "formspec.h"             // for FsChainFind, FsChainAdd, kFsLowranceusr4, FormatSpecificData
 #include "gbfile.h"               // for gbfgetint32, gbfputint32, gbfputint16, gbfgetc, gbfgetint16, gbfwrite, gbfputc, gbfeof, gbfgetflt, gbfclose, gbfgetdbl, gbfopen_le, gbfputdbl, gbfputs, gbfile, gbfputflt, gbfread, gbfseek
+#include "mkshort.h"              // for MakeShort
 #include "src/core/datetime.h"    // for DateTime
 
 
@@ -433,7 +434,7 @@ private:
 
   gbfile*        file_in{};
   gbfile*        file_out{};
-  short_handle   mkshort_handle{};
+  MakeShort*     mkshort_handle{};
 
   route_head*    trk_head{};
   route_head*    rte_head{};
diff --git a/main.cc b/main.cc
index 3c20a5d7bb485cf308ba62e394f1e9820c9684f5..f99f47903626f8f1fde7aeb7af3f67fcef151c7b 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -50,6 +50,7 @@
 #include "gbversion.h"                // for VERSION_SHA
 #include "inifile.h"                  // for inifile_done, inifile_init
 #include "jeeps/gpsmath.h"            // for GPS_Lookup_Datum_Index
+#include "mkshort.h"                  // for MakeShort
 #include "session.h"                  // for start_session, session_exit, session_init
 #include "src/core/datetime.h"        // for DateTime
 #include "src/core/file.h"            // for File
@@ -213,14 +214,6 @@ signal_handler(int sig)
 class FallbackOutput
 {
 public:
-  FallbackOutput() : mkshort_handle(mkshort_new_handle()) {}
-  // delete copy and move constructors and assignment operators.
-  // The defaults are not appropriate, and we haven't implemented proper ones.
-  FallbackOutput(const FallbackOutput&) = delete;
-  FallbackOutput& operator=(const FallbackOutput&) = delete;
-  FallbackOutput(FallbackOutput&&) = delete;
-  FallbackOutput& operator=(FallbackOutput&&) = delete;
-  ~FallbackOutput() {mkshort_del_handle(&mkshort_handle);}
 
   void waypt_disp(const Waypoint* wpt)
   {
@@ -232,7 +225,7 @@ public:
     if (!wpt->description.isEmpty()) {
       printf("%s/%s",
              global_opts.synthesize_shortnames ?
-             qPrintable(mkshort(mkshort_handle, wpt->description)) :
+             qPrintable(mkshort_handle.mkshort(wpt->description)) :
              qPrintable(wpt->shortname),
              qPrintable(wpt->description));
     }
@@ -244,7 +237,7 @@ public:
   }
 
 private:
-  short_handle mkshort_handle;
+  MakeShort mkshort_handle;
 };
 
 static void
index 4ad3fc47f14722197c395c72dc8fcb5f1208d808..8bf839b417455dfa90fe63e310a8e44b5ca961f9 100644 (file)
 
  */
 
+#include "mkshort.h"
+
 #include <cassert>     // for assert
 #include <cctype>      // for isspace, isdigit
 
 #include <QByteArray>  // for QByteArray
 #include <QChar>       // for QChar, QChar::ReplacementCharacter
-#include <QHash>       // for QHash, QHash<>::iterator, qHash, QHash<>::size_type
 #include <QString>     // for QString
 #include <QVector>     // for QVector
 #include <Qt>          // for CaseInsensitive
 #include "geocache.h"  // for Geocache
 
 
-#define MYNAME "mkshort"
-
-static const QByteArray vowels("aeiouAEIOU");
-static constexpr int default_target_len = 8;
-static constexpr const char default_badchars[] = "\"$.,'!-";
-
-class ShortNameKey;
-using ShortNameHash = QHash<ShortNameKey, int>;
-class ShortNameKey
-{
-public:
-  ShortNameKey(const QByteArray& name) : shortname(name) {} /* converting constructor */
-
-  friend qhash_result_t qHash(const ShortNameKey& key, qhash_result_t seed = 0) noexcept
-  {
-    // We hash all strings as upper case.
-    return qHash(key.shortname.toUpper(), seed);
-  }
-
-  QByteArray shortname;
-};
+const QByteArray MakeShort::vowels = "aeiouAEIOU";
 
-inline bool operator==(const ShortNameKey& lhs, const ShortNameKey& rhs) noexcept
-{
-  return lhs.shortname.compare(rhs.shortname, Qt::CaseInsensitive) == 0;
-}
-
-struct  mkshort_handle_imp {
-  int target_len{default_target_len};
-  QByteArray badchars{default_badchars};
-  QByteArray goodchars;
-  QByteArray defname{"WPT"};
-  ShortNameHash namelist;
-
-  /* Various internal flags */
-  bool mustupper{false};
-  bool whitespaceok{true};
-  bool repeating_whitespaceok{false};
-  bool must_uniq{true};
-};
-
-struct replacement_t {
-  QByteArray orig;
-  QByteArray replacement;
-};
-static const QVector<replacement_t> replacements = {
+const QVector<MakeShort::replacement_t> MakeShort::replacements = {
   {"zero", "0"},
   {"one", "1"},
   {"two", "2"},
@@ -92,26 +50,18 @@ static const QVector<replacement_t> replacements = {
   {"nine", "9"}
 };
 
-short_handle
-mkshort_new_handle()
+void MakeShort::mkshort_add_to_list(QByteArray& name, bool is_utf8)
 {
-  return new mkshort_handle_imp;
-}
-
-static
-void
-mkshort_add_to_list(mkshort_handle_imp* h, QByteArray& name, bool is_utf8)
-{
-  while (h->namelist.contains(name)) {
-    auto& conflictctr = h->namelist[name];
+  while (namelist_.contains(name)) {
+    auto& conflictctr = namelist_[name];
 
     QByteArray suffix(".");
     suffix.append(QByteArray::number(++conflictctr));
     int suffixcnt = suffix.size();
 
-    if (name.size() + suffixcnt <= h->target_len) {
+    if (name.size() + suffixcnt <= target_len_) {
       name.append(suffix);
-    } else if (int keepcnt = h->target_len - suffixcnt; keepcnt >= 0) {
+    } else if (int keepcnt = target_len_ - suffixcnt; keepcnt >= 0) {
       if (is_utf8) {
         QString result = grapheme_truncate(QString::fromUtf8(name), keepcnt);
         name = result.toUtf8().append(suffix);
@@ -124,42 +74,14 @@ mkshort_add_to_list(mkshort_handle_imp* h, QByteArray& name, bool is_utf8)
     }
   }
 
-  h->namelist.insert(name, 0);
-}
-
-void
-mkshort_del_handle(short_handle* h)
-{
-  if (!h) {
-    return;
-  }
-
-  auto* hdr = (mkshort_handle_imp*) *h;
-
-  if (!hdr) {
-    return;
-  }
-
-#if 0
-  for (auto it = hdr->namelist.cbegin(), end = hdr->namelist.cend(); it != end; ++it) {
-    if (global_opts.verbose_status >= 2 && it.value()->conflictctr) {
-      fprintf(stderr, "%d Output name conflicts: '%s'\n",
-              it.value()->conflictctr, it.key().shortname.constData());
-    }
-  }
-#endif
-
-  delete hdr;
-  *h = nullptr;
+  namelist_.insert(name, 0);
 }
 
 /*
  * This is the stuff that makes me ashamed to be a C programmer...
  */
 
-static
-bool
-delete_last_vowel(int start, QByteArray& iostring)
+bool MakeShort::delete_last_vowel(int start, QByteArray& iostring)
 {
   /*
    * Basically implement strrchr.
@@ -184,8 +106,7 @@ delete_last_vowel(int start, QByteArray& iostring)
  * Open the slippery slope of literal replacement.   Right now, replacements
  * are made only at the end of the string.
  */
-void
-replace_constants(QByteArray& s)
+void MakeShort::replace_constants(QByteArray& s)
 {
   for (const auto& r : replacements) {
     /*
@@ -202,59 +123,50 @@ replace_constants(QByteArray& s)
   }
 }
 
-
 /*
  * Externally callable function to set the max length of the
  * strings returned by mkshort().  0 resets to default.
  */
-void
-setshort_length(short_handle h, int l)
+void MakeShort::set_length(int l)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
   if (l < 0) {
     fatal("mkshort: short length must be non-negative.\n");
   } else if (l == 0) {
-    hdl->target_len = default_target_len;
+    target_len_ = default_target_len;
   } else {
-    hdl->target_len = l;
+    target_len_ = l;
   }
 }
 
 /*
- * Call with L nonzero if whitespace in the generated shortname is wanted.
+ * Call with ok = true if whitespace in the generated shortname is wanted.
  */
 
-void
-setshort_whitespace_ok(short_handle h, int l)
+void MakeShort::set_whitespace_ok(bool ok)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
-  hdl->whitespaceok = l;
+  whitespaceok_ = ok;
 }
 
 /*
- * Call with L nonzero if multiple consecutive whitespace in the
+ * Call with ok = true if multiple consecutive whitespace in the
  * generated shortname is wanted.
  */
 
-void
-setshort_repeating_whitespace_ok(short_handle h, int l)
+void MakeShort::set_repeating_whitespace_ok(bool ok)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
-  hdl->repeating_whitespaceok = l;
+  repeating_whitespaceok_ = ok;
 }
 
 /*
  * Set default name given to a waypoint if no valid is possible
  * because it was filtered by charsets or null or whatever.
  */
-void
-setshort_defname(short_handle h, const char* s)
+void MakeShort::set_defname(const char* s)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
   if (s == nullptr) {
-    fatal("setshort_defname called without a valid name.");
+    fatal("set_defname called without a valid name.");
   }
-  hdl->defname = s;
+  defname_ = s;
 }
 
 /*
@@ -262,57 +174,45 @@ setshort_defname(short_handle h, const char* s)
  * that must never appear in a string returned by mkshort.  NULL
  * resets to default.
  */
-void
-setshort_badchars(short_handle h, const char* s)
+void MakeShort::set_badchars(const char* s)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
-
-  hdl->badchars = s ? s : default_badchars;
+  badchars_ = (s  == nullptr)? default_badchars : s;
 }
 
 /*
  * Only characters that appear in *s are "whitelisted" to appear
  * in generated names.
  */
-void
-setshort_goodchars(short_handle h, const char* s)
+void MakeShort::set_goodchars(const char* s)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
-
-  if (s != nullptr) {
-    hdl->goodchars = s;
+  if (s == nullptr) {
+    goodchars_.clear();
   } else {
-    hdl->goodchars.clear();
+    goodchars_ = s;
   }
 }
 
 /*
- *  Call with i non-zero if generated names must be uppercase only.
+ *  Call with must = true if generated names must be uppercase only.
  */
-void
-setshort_mustupper(short_handle h, int i)
+void MakeShort::set_mustupper(bool must)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
-  hdl->mustupper = i;
+  mustupper_ = must;
 }
 
 
 /*
- *  Call with i zero if the generated names don't have to be unique.
+ *  Call with must = false if the generated names don't have to be unique.
  *  (By default, they are.)
  */
-void
-setshort_mustuniq(short_handle h, int i)
+void MakeShort::set_mustuniq(bool must)
 {
-  auto* hdl = (mkshort_handle_imp*) h;
-  hdl->must_uniq = i;
+  must_uniq_ = must;
 }
 
-QByteArray
-mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
+QByteArray MakeShort::mkshort(const QByteArray& istring, bool is_utf8)
 {
   QByteArray ostring;
-  auto* hdl = (mkshort_handle_imp*) h;
 
   if (is_utf8) {
     /* clean UTF-8 string */
@@ -332,7 +232,7 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
    * the new seven digit geocache numbers and special case whacking
    * the 'G' off the front.
    */
-  if ((hdl->target_len == 6) && (ostring.size() == 7) &&
+  if ((target_len_ == 6) && (ostring.size() == 7) &&
       ostring.startsWith("GC")) {
     ostring.remove(0, 1);
   }
@@ -340,7 +240,7 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
   /*
    * Whack leading "[Tt]he "
    */
-  if ((ostring.size() > (hdl->target_len + 4)) &&
+  if ((ostring.size() > (target_len_ + 4)) &&
       (ostring.startsWith("The ") || ostring.startsWith("the "))) {
     ostring.remove(0, 4);
   }
@@ -348,7 +248,7 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
   /* In all cases eliminate leading and trailing whitespace */
   ostring = ostring.trimmed();
 
-  if (!hdl->whitespaceok) {
+  if (!whitespaceok_) {
     /*
      * Eliminate Whitespace
      */
@@ -361,7 +261,7 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
     }
   }
 
-  if (hdl->mustupper) {
+  if (mustupper_) {
     ostring = ostring.toUpper();
   }
 
@@ -378,10 +278,10 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
     QByteArray tstring;
     ostring.swap(tstring);
     for (const auto ch : qAsConst(tstring)) {
-      if (hdl->badchars.contains(ch)) {
+      if (badchars_.contains(ch)) {
         continue;
       }
-      if (!hdl->goodchars.isEmpty() && (!hdl->goodchars.contains(ch))) {
+      if (!goodchars_.isEmpty() && (!goodchars_.contains(ch))) {
         continue;
       }
       ostring.append(ch);
@@ -395,7 +295,7 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
    * operations that removed character(s) before and/or after whitespace.
    * Conditionally simplify embedded whitespace.
    */
-  ostring = hdl->repeating_whitespaceok? ostring.trimmed() : ostring.simplified();
+  ostring = repeating_whitespaceok_? ostring.trimmed() : ostring.simplified();
 
   /*
    * Toss vowels to approach target length, but don't toss them
@@ -414,9 +314,9 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
    *
    * It also helps units with speech synthesis.
    */
-  bool replaced = hdl->target_len < 15;
+  bool replaced = target_len_ < 15;
 
-  while (replaced && (ostring.size() > hdl->target_len)) {
+  while (replaced && (ostring.size() > target_len_)) {
     replaced = delete_last_vowel(2, ostring);
   }
 
@@ -433,18 +333,18 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
    * If the numeric component alone is longer than our target string
    * length, use the trailing part of the the numeric component.
    */
-  if (int delcnt = ostring.size() - hdl->target_len; delcnt > 0) {
+  if (int delcnt = ostring.size() - target_len_; delcnt > 0) {
     int suffixcnt = 0;
     for (auto it = ostring.crbegin(); it != ostring.crend(); ++it) {
       if (isdigit(*it)) {
         ++suffixcnt;
       }
-      if (suffixcnt == hdl->target_len) {
+      if (suffixcnt == target_len_) {
         break;
       }
     }
 
-    int keepcnt = hdl->target_len - suffixcnt;
+    int keepcnt = target_len_ - suffixcnt;
     assert(keepcnt >= 0);
 
     if (is_utf8) {
@@ -463,27 +363,25 @@ mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
    * let the must_uniq code handle it.
    */
   if (ostring.isEmpty()) {
-    ostring = hdl->defname;
+    ostring = defname_;
   }
 
-  if (hdl->must_uniq) {
-    mkshort_add_to_list(hdl, ostring, is_utf8);
+  if (must_uniq_) {
+    mkshort_add_to_list(ostring, is_utf8);
   }
   return ostring;
 }
 
-QString
-mkshort(short_handle h, const QString& istring)
+QString MakeShort::mkshort(const QString& istring)
 {
-  return mkshort(h, istring.toUtf8(), true);
+  return mkshort(istring.toUtf8(), true);
 }
 
 /*
  * As above, but arg list is a waypoint so we can centralize
  * the code that considers the alternate sources.
  */
-QString
-mkshort_from_wpt(short_handle h, const Waypoint* wpt)
+QString MakeShort::mkshort_from_wpt(const Waypoint* wpt)
 {
   /* This probably came from a Groundspeak Pocket Query
    * so use the 'cache name' instead of the description field
@@ -492,20 +390,20 @@ mkshort_from_wpt(short_handle h, const Waypoint* wpt)
    */
   if (wpt->gc_data->diff && wpt->gc_data->terr &&
       !wpt->notes.isEmpty()) {
-    return mkshort(h, wpt->notes);
+    return mkshort(wpt->notes);
   }
 
   if (!wpt->description.isEmpty()) {
-    return mkshort(h, wpt->description);
+    return mkshort(wpt->description);
   }
 
   if (!wpt->notes.isEmpty()) {
-    return mkshort(h, wpt->notes);
+    return mkshort(wpt->notes);
   }
 
   /* Should probably never actually happen... */
   /* O.K.: But this can happen (waypoints transformed from trackpoints )! */
   /*       Now we return every time a valid entity." */
 
-  return mkshort(h, wpt->shortname);
+  return mkshort(wpt->shortname);
 }
diff --git a/mkshort.h b/mkshort.h
new file mode 100644 (file)
index 0000000..a672a0d
--- /dev/null
+++ b/mkshort.h
@@ -0,0 +1,109 @@
+/*
+    Generate unique short names.
+
+    Copyright (C) 2003-2006, 2023 Robert Lipe, robertlipe+source@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+
+#ifndef MKSHORT_H_INCLUDED_
+#define MKSHORT_H_INCLUDED_
+
+#include <QByteArray>  // for QByteArray
+#include <QHash>       // for QHash, QHash<>::iterator, qHash, QHash<>::size_type
+#include <QString>     // for QString
+#include <QVector>     // for QVector
+#include <Qt>          // for CaseInsensitive
+
+#include "defs.h"
+
+
+class MakeShort
+{
+public:
+
+  /* Member Functions */
+
+  void set_length(int l);
+  void set_whitespace_ok(bool ok);
+  void set_repeating_whitespace_ok(bool ok);
+  void set_defname(const char* s);
+  void set_badchars(const char* s);
+  void set_goodchars(const char* s);
+  void set_mustupper(bool must);
+  void set_mustuniq(bool must);
+  QByteArray mkshort(const QByteArray& istring, bool is_utf8);
+  QString mkshort(const QString& istring);
+  QString mkshort_from_wpt(const Waypoint* wpt);
+
+private:
+
+  /* Types */
+
+  class ShortNameKey;
+  using ShortNameHash = QHash<ShortNameKey, int>;
+  class ShortNameKey
+  {
+  public:
+    ShortNameKey(const QByteArray& name) : shortname(name) {} /* converting constructor */
+
+    friend qhash_result_t qHash(const ShortNameKey& key, qhash_result_t seed = 0) noexcept
+    {
+      // We hash all strings as upper case.
+      return qHash(key.shortname.toUpper(), seed);
+    }
+    bool operator==(const ShortNameKey& other) const
+    {
+      return shortname.compare(other.shortname, Qt::CaseInsensitive) == 0;
+    }
+
+  private:
+    QByteArray shortname;
+  };
+
+  struct replacement_t {
+    QByteArray orig;
+    QByteArray replacement;
+  };
+
+  /* Constants */
+
+  static const QByteArray vowels;
+  static constexpr int default_target_len = 8;
+  static constexpr const char default_badchars[] = "\"$.,'!-";
+  static const QVector<replacement_t> replacements;
+
+  /* Member Functions */
+
+  void mkshort_add_to_list(QByteArray& name, bool is_utf8);
+  static bool delete_last_vowel(int start, QByteArray& iostring);
+  static void replace_constants(QByteArray& s);
+
+  /* Data Members */
+
+  int target_len_{default_target_len};
+  QByteArray badchars_{default_badchars};
+  QByteArray goodchars_;
+  QByteArray defname_{"WPT"};
+  ShortNameHash namelist_;
+
+  /* Various internal flags */
+  bool mustupper_{false};
+  bool whitespaceok_{true};
+  bool repeating_whitespaceok_{false};
+  bool must_uniq_{true};
+};
+#endif // MKSHORT_H_INCLUDED_
diff --git a/nmea.cc b/nmea.cc
index 442d5857a958fcf7161f35f9e48539891603b21e..84129cd0a2106a11d505319ed30930a480abc5cc 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -45,6 +45,7 @@
 #include "gbfile.h"                // for gbfprintf, gbfflush, gbfclose, gbfopen, gbfgetstr, gbfile
 #include "gbser.h"                 // for gbser_set_speed, gbser_flush, gbser_read_line, gbser_deinit, gbser_init, gbser_write
 #include "jeeps/gpsmath.h"         // for GPS_Lookup_Datum_Index, GPS_Math_Known_Datum_To_WGS84_M
+#include "mkshort.h"               // for MakeShort
 #include "src/core/datetime.h"     // for DateTime
 #include "src/core/logging.h"      // for Warning
 
@@ -299,8 +300,8 @@ NmeaFormat::wr_init(const QString& fname)
     }
   }
 
-  mkshort_handle = mkshort_new_handle();
-  setshort_length(mkshort_handle, xstrtoi(snlenopt, nullptr, 10));
+  mkshort_handle = new MakeShort;
+  mkshort_handle->set_length(xstrtoi(snlenopt, nullptr, 10));
 
   if (opt_gisteq) {
     opt_gpgga = nullptr;
@@ -313,7 +314,8 @@ void
 NmeaFormat::wr_deinit()
 {
   gbfclose(file_out);
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
 }
 
 void
@@ -1164,9 +1166,9 @@ NmeaFormat::nmea_wayptpr(const Waypoint* wpt) const
   double lat = degrees2ddmm(wpt->latitude);
   double lon = degrees2ddmm(wpt->longitude);
   if (global_opts.synthesize_shortnames) {
-    s = mkshort_from_wpt(mkshort_handle, wpt);
+    s = mkshort_handle->mkshort_from_wpt(wpt);
   } else {
-    s = mkshort(mkshort_handle, wpt->shortname);
+    s = mkshort_handle->mkshort(wpt->shortname);
   }
 
   snprintf(obuf, sizeof(obuf),  "GPWPL,%08.3f,%c,%09.3f,%c,%s",
diff --git a/nmea.h b/nmea.h
index d612abdbb1f3993a2262ff9f0e4492e87388fa77..e265f051b40045409ca099f27295dd5779c8fce2 100644 (file)
--- a/nmea.h
+++ b/nmea.h
@@ -33,6 +33,7 @@
 #include "defs.h"
 #include "format.h"           // for Format
 #include "gbfile.h"           // for gbfile
+#include "mkshort.h"          // for MakeShort
 
 
 class NmeaFormat : public Format
@@ -121,7 +122,7 @@ private:
 
   gbfile* file_in{}, *file_out{};
   route_head* trk_head{};
-  short_handle mkshort_handle{};
+  MakeShort* mkshort_handle{};
   preferred_posn_type posn_type{};
   read_mode_type read_mode{};
   QDateTime prev_datetime;
diff --git a/ozi.cc b/ozi.cc
index 14473ac8a14b3210b9b83ecc5c8ef76f51ee131d..74e33262a80e89d83a979594965600592a00e259 100644 (file)
--- a/ozi.cc
+++ b/ozi.cc
@@ -55,6 +55,7 @@
 #include "csv_util.h"             // for csv_stringclean
 #include "formspec.h"             // for FsChainAdd, FsChainFind, kFsOzi, FormatSpecificData
 #include "jeeps/gpsmath.h"        // for GPS_Math_Known_Datum_To_WGS84_M
+#include "mkshort.h"              // for MakeShort
 #include "src/core/datetime.h"    // for DateTime
 #include "src/core/textstream.h"  // for TextStream
 
@@ -77,7 +78,7 @@ struct ozi_fsdata : FormatSpecificData {
 
 static gpsbabel::TextStream* stream = nullptr;
 
-static short_handle mkshort_handle;
+static MakeShort* mkshort_handle;
 static route_head* trk_head;
 static route_head* rte_head;
 
@@ -437,7 +438,6 @@ rd_init(const QString& fname)
 {
   ozi_open_io(fname, QFile::ReadOnly);
 
-  mkshort_handle = mkshort_new_handle();
   ozi_init_units(0);
 }
 
@@ -445,8 +445,6 @@ static void
 rd_deinit()
 {
   ozi_close_io();
-
-  mkshort_del_handle(&mkshort_handle);
 }
 
 static void
@@ -460,26 +458,26 @@ wr_init(const QString& fname)
 
   ozi_ofname = fname;
 
-  mkshort_handle = mkshort_new_handle();
+  mkshort_handle = new MakeShort;
 
   /* set mkshort options from the command line if applicable */
   if (global_opts.synthesize_shortnames) {
 
-    setshort_length(mkshort_handle, xstrtoi(snlenopt, nullptr, 10));
+    mkshort_handle->set_length(xstrtoi(snlenopt, nullptr, 10));
 
     if (snwhiteopt) {
-      setshort_whitespace_ok(mkshort_handle, xstrtoi(snwhiteopt, nullptr, 10));
+      mkshort_handle->set_whitespace_ok(xstrtoi(snwhiteopt, nullptr, 10));
     }
 
     if (snupperopt) {
-      setshort_mustupper(mkshort_handle, xstrtoi(snupperopt, nullptr, 10));
+      mkshort_handle->set_mustupper(xstrtoi(snupperopt, nullptr, 10));
     }
 
     if (snuniqueopt) {
-      setshort_mustuniq(mkshort_handle, xstrtoi(snuniqueopt, nullptr, 10));
+      mkshort_handle->set_mustuniq(xstrtoi(snuniqueopt, nullptr, 10));
     }
 
-    setshort_badchars(mkshort_handle, "\",");
+    mkshort_handle->set_badchars("\",");
   }
 
   ozi_init_units(1);
@@ -492,7 +490,8 @@ wr_deinit()
   ozi_close_io();
   ozi_ofname.clear();
 
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
 }
 
 static void
@@ -881,7 +880,7 @@ ozi_waypt_pr(const Waypoint* wpt)
   if ((wpt->shortname.isEmpty()) || (global_opts.synthesize_shortnames)) {
     if (!wpt->description.isEmpty()) {
       if (global_opts.synthesize_shortnames) {
-        shortname = mkshort_from_wpt(mkshort_handle, wpt);
+        shortname = mkshort_handle->mkshort_from_wpt(wpt);
       } else {
         shortname = csv_stringclean(wpt->description, BADCHARS);
       }
diff --git a/text.cc b/text.cc
index b582abf5e26f2bf0f25b50001f88e0baeabb1099..e4ed3789285f80762e93d11132dac552ba3bd401 100644 (file)
--- a/text.cc
+++ b/text.cc
@@ -48,7 +48,7 @@ TextFormat::wr_init(const QString& fname)
     file_out = new gpsbabel::TextStream;
     file_out->open(fname, QIODevice::WriteOnly, MYNAME);
   }
-  mkshort_handle = mkshort_new_handle();
+  mkshort_handle = new MakeShort;
 }
 
 void
@@ -59,7 +59,8 @@ TextFormat::wr_deinit()
     delete file_out;
     file_out = nullptr;
   }
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
+  mkshort_handle = nullptr;
   output_name.clear();
 }
 
@@ -90,7 +91,7 @@ TextFormat::text_disp(const Waypoint* wpt)
   if (wpt->altitude != unknown_alt) {
     position += QStringLiteral(" alt:%1").arg((int)((altunits[0]=='f') ? METERS_TO_FEET(wpt->altitude) : wpt->altitude));
   }
-  QString sn = global_opts.synthesize_shortnames ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname;
+  QString sn = global_opts.synthesize_shortnames ? mkshort_handle->mkshort_from_wpt(wpt) : wpt->shortname;
   *file_out << sn.leftJustified(16) << "  " <<  position.rightJustified(59) << "\n";
 
   if (wpt->description != wpt->shortname) {
@@ -196,7 +197,7 @@ TextFormat::write()
   if (!suppresssep && !split_output) {
     *file_out << "-----------------------------------------------------------------------------\n";
   }
-  setshort_length(mkshort_handle, 6);
+  mkshort_handle->set_length(6);
   auto text_disp_lambda = [this](const Waypoint* waypointp)->void {
     text_disp(waypointp);
   };
diff --git a/text.h b/text.h
index 3305a92b00a9c5e515651cda2dde8e2ffc5e48c2..37ad2b97dba5dee5f3505d4c3bd820d51f7aa381 100644 (file)
--- a/text.h
+++ b/text.h
@@ -26,6 +26,7 @@
 
 #include "defs.h"
 #include "format.h"               // for Format
+#include "mkshort.h"              // for MakeShort
 #include "src/core/textstream.h"  // for TextStream
 
 
@@ -60,7 +61,7 @@ private:
   /* Data Members */
 
   gpsbabel::TextStream* file_out{nullptr};
-  short_handle mkshort_handle{};
+  MakeShort* mkshort_handle{};
 
   char* suppresssep = nullptr;
   char* txt_encrypt = nullptr;
diff --git a/tpg.cc b/tpg.cc
index 4e1e337babcb19d5f2d43286ca67b13ff5c448bb..615a08de2cd8b72ebbe8d2e2b9305b9653a26c66 100644 (file)
--- a/tpg.cc
+++ b/tpg.cc
@@ -32,6 +32,7 @@
 #include "defs.h"
 #include "gbfile.h"         // for gbfwrite, gbfgetint16, gbfputint16, gbfclose
 #include "jeeps/gpsmath.h"  // for GPS_Lookup_Datum_Index, GPS_Math_Known_Da...
+#include "mkshort.h"        // for MakeShort
 
 
 #define MYNAME "TPG"
@@ -41,7 +42,7 @@
 
 static gbfile* tpg_file_in;
 static gbfile* tpg_file_out;
-static short_handle mkshort_handle;
+static MakeShort* mkshort_handle;
 static char* tpg_datum_opt;
 static int tpg_datum_idx;
 
@@ -94,14 +95,14 @@ tpg_wr_init(const QString& fname)
 {
   tpg_common_init();
   tpg_file_out = gbfopen_le(fname, "wb", MYNAME);
-  mkshort_handle = mkshort_new_handle();
+  mkshort_handle = new MakeShort;
   waypt_out_count = 0;
 }
 
 static void
 tpg_wr_deinit()
 {
-  mkshort_del_handle(&mkshort_handle);
+  delete mkshort_handle;
   gbfclose(tpg_file_out);
 }
 
@@ -188,7 +189,7 @@ tpg_waypt_pr(const Waypoint* wpt)
   if ((wpt->shortname.isEmpty()) || (global_opts.synthesize_shortnames)) {
     if (!wpt->description.isEmpty()) {
       if (global_opts.synthesize_shortnames) {
-        shortname = mkshort_from_wpt(mkshort_handle, wpt);
+        shortname = mkshort_handle->mkshort_from_wpt(wpt);
       } else {
         shortname = wpt->description;
       }
@@ -291,9 +292,9 @@ tpg_write()
   int s = waypt_count();
 
   if (global_opts.synthesize_shortnames) {
-    setshort_length(mkshort_handle, 32);
-    setshort_whitespace_ok(mkshort_handle, 1);
-    setshort_mustupper(mkshort_handle, 1);
+    mkshort_handle->set_length(32);
+    mkshort_handle->set_whitespace_ok(true);
+    mkshort_handle->set_mustupper(true);
   }
 
   if (s > MAXTPGOUTPUTPINS) {
diff --git a/vcf.cc b/vcf.cc
index ee48acbdf92f08a15c8ecae2638bc0c511031a8d..fd3e90844a1b0f5e76c8c7882e79717e0e84b110 100644 (file)
--- a/vcf.cc
+++ b/vcf.cc
@@ -31,7 +31,6 @@
 
 
 static gbfile* file_out;
-static short_handle mkshort_handle;
 
 static char* vcf_encrypt = nullptr;
 
@@ -49,14 +48,12 @@ static void
 wr_init(const QString& fname)
 {
   file_out = gbfopen(fname, "w", MYNAME);
-  mkshort_handle = mkshort_new_handle();
 }
 
 static void
 wr_deinit()
 {
   gbfclose(file_out);
-  mkshort_del_handle(&mkshort_handle);
 }
 
 /*
@@ -132,7 +129,6 @@ vcf_disp(const Waypoint* wpt)
 static void
 data_write()
 {
-  setshort_length(mkshort_handle, 6);
   waypt_disp_all(vcf_disp);
 }
 
diff --git a/xcsv.cc b/xcsv.cc
index fa7e6dbdcd15e1666a7ec72ab53f98db578c9813..2794c0f7d65ca6594675c59cf1dc5570154e2430 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
@@ -1013,7 +1013,7 @@ XcsvFormat::xcsv_waypt_pr(const Waypoint* wpt)
   if (wpt->shortname.isEmpty() || global_opts.synthesize_shortnames) {
     if (!wpt->description.isEmpty()) {
       if (global_opts.synthesize_shortnames) {
-        shortname = mkshort_from_wpt(xcsv_file->mkshort_handle, wpt);
+        shortname = xcsv_file->mkshort_handle.mkshort_from_wpt(wpt);
       } else {
         shortname = csv_stringclean(wpt->description, xcsv_style->badchars);
       }
@@ -1091,10 +1091,10 @@ XcsvFormat::xcsv_waypt_pr(const Waypoint* wpt)
     case XcsvStyle::XT_ANYNAME: {
       QString anyname = wpt->shortname;
       if (anyname.isEmpty()) {
-        anyname = mkshort(xcsv_file->mkshort_handle, wpt->description);
+        anyname = xcsv_file->mkshort_handle.mkshort(wpt->description);
       }
       if (anyname.isEmpty()) {
-        anyname = mkshort(xcsv_file->mkshort_handle, wpt->description);
+        anyname = xcsv_file->mkshort_handle.mkshort(wpt->description);
       }
       if (anyname.isEmpty()) {
         anyname = wpt->notes;
@@ -1954,32 +1954,32 @@ XcsvFormat::wr_init(const QString& fname)
   xcsv_file->fname = fname;
 
   if (xcsv_style->shortlen) {
-    setshort_length(xcsv_file->mkshort_handle, *xcsv_style->shortlen);
+    xcsv_file->mkshort_handle.set_length(*xcsv_style->shortlen);
   }
   if (xcsv_style->whitespace_ok) {
-    setshort_whitespace_ok(xcsv_file->mkshort_handle, *xcsv_style->whitespace_ok);
+    xcsv_file->mkshort_handle.set_whitespace_ok(*xcsv_style->whitespace_ok);
   }
 
   /* set mkshort options from the command line */
   if (global_opts.synthesize_shortnames) {
 
     if (snlenopt) {
-      setshort_length(xcsv_file->mkshort_handle, xstrtoi(snlenopt, nullptr, 10));
+      xcsv_file->mkshort_handle.set_length(xstrtoi(snlenopt, nullptr, 10));
     }
 
     if (snwhiteopt) {
-      setshort_whitespace_ok(xcsv_file->mkshort_handle, xstrtoi(snwhiteopt, nullptr, 10));
+      xcsv_file->mkshort_handle.set_whitespace_ok(xstrtoi(snwhiteopt, nullptr, 10));
     }
 
     if (snupperopt) {
-      setshort_mustupper(xcsv_file->mkshort_handle, xstrtoi(snupperopt, nullptr, 10));
+      xcsv_file->mkshort_handle.set_mustupper(xstrtoi(snupperopt, nullptr, 10));
     }
 
     if (snuniqueopt) {
-      setshort_mustuniq(xcsv_file->mkshort_handle, xstrtoi(snuniqueopt, nullptr, 10));
+      xcsv_file->mkshort_handle.set_mustuniq(xstrtoi(snuniqueopt, nullptr, 10));
     }
 
-    setshort_badchars(xcsv_file->mkshort_handle, CSTR(xcsv_style->badchars));
+    xcsv_file->mkshort_handle.set_badchars(CSTR(xcsv_style->badchars));
 
   }
 
diff --git a/xcsv.h b/xcsv.h
index 0cbfd13454b544a193c8b727f18b19fa5f368c85..3a586c0c5b7b290026f64b1775b9dd6afd14d49e 100644 (file)
--- a/xcsv.h
+++ b/xcsv.h
@@ -37,8 +37,9 @@
 #include <QtGlobal>               // for qRound64
 
 #include "defs.h"
-#include "format.h"
-#include "garmin_fs.h"
+#include "format.h"               // for Format
+#include "garmin_fs.h"            // for garmin_fs_t
+#include "mkshort.h"              // for MakeShort
 #include "src/core/datetime.h"    // for DateTime
 #include "src/core/textstream.h"  // for TextStream
 
@@ -239,7 +240,7 @@ public:
   std::optional<int> shortlen;
 
   /* SHORTWHITE from style file */
-  std::optional<int> whitespace_ok;
+  std::optional<bool> whitespace_ok;
 
 private:
   /* Types */
@@ -298,28 +299,13 @@ private:
   class XcsvFile
   {
   public:
-    /* Special Member Functions */
-
-    XcsvFile() : mkshort_handle(mkshort_new_handle()) {}
-    // delete copy and move constructors and assignment operators.
-    // The defaults are not appropriate, and we haven't implemented proper ones.
-    XcsvFile(const XcsvFile&) = delete;
-    XcsvFile& operator=(const XcsvFile&) = delete;
-    XcsvFile(XcsvFile&&) = delete;
-    XcsvFile& operator=(XcsvFile&&) = delete;
-    ~XcsvFile()
-    {
-      if (mkshort_handle != nullptr) {
-        mkshort_del_handle(&mkshort_handle);
-      }
-    }
 
     /* Data Members */
 
     gpsbabel::TextStream stream;
     QString fname;
     int gps_datum_idx{-1};             /* result of GPS_Lookup_Datum_Index */
-    short_handle mkshort_handle{nullptr};
+    MakeShort mkshort_handle;
   };
 
   struct xcsv_parse_data {